from rest_framework import serializers
from rest_framework.generics import ListCreateAPIView
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.filters import BaseFilterBackend
from api.utils.auth import UserAuthentication
from api.utils.auth import GeneralAuthorization
from django.forms import model_to_dict
from django.db import transaction
from django.db.models import F
from api import models


class NewsPagination(LimitOffsetPagination):
    '''
    动态分页
    '''
    default_limit = 5
    max_limit = 50

    def get_offset(self, request):
        return 0

class NewsBaseFilterBackend(BaseFilterBackend):
    '''
    处理get的参数的max
    '''
    def filter_queryset(self, request, queryset, view):
        max=request.query_params.get('max')
        if max:
            return queryset.filter(id__gt=max)
        else:
            return queryset

class NewsListModelSerializer(serializers.ModelSerializer):
    '''
    展示动态序列化
    '''
    user=serializers.SerializerMethodField()
    topic=serializers.SerializerMethodField()

    class Meta:
        model=models.News
        exclude = ['address',]

    def get_user(self,obj):
        return model_to_dict(obj.user,fields=['pk','avatar','nickname'])
    def get_topic(self,obj):
        topic=obj.topic
        if topic:
            return model_to_dict(topic,fields=['title','count'])


class NewsPicSerializer(serializers.Serializer):
    ''''
    新闻图片序列化
    '''
    key=serializers.CharField()
    cos_path=serializers.CharField()



class NewsCreateModelSerializer(serializers.ModelSerializer):

    image_list=NewsPicSerializer(many=True)

    class Meta:
        model=models.News
        exclude = ['user', 'viewer_count', 'comment_count', 'favor_count']

    def create(self, validated_data):
        image_list=validated_data.pop('image_list')
        with transaction.atomic():
            instance=models.News.objects.create(**validated_data)
            data_list=models.NewsDetail.objects.bulk_create([models.NewsDetail(news=instance,**info) for info in image_list])
            instance.image_list=data_list
            if instance.topic:
                models.Topic.objects.filter(pk=instance.topic_id).update(count=F('count')+1)
            return instance

class NewsApiView(ListCreateAPIView):

    queryset = models.News.objects
    filter_backends = [NewsBaseFilterBackend,]
    pagination_class = NewsPagination

    def get_serializer_class(self):
        if self.request.method == 'GET':
            return NewsListModelSerializer
        if self.request.method == 'POST':
            return NewsCreateModelSerializer

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

    def get_authenticators(self):
        if self.request.method == 'POST':
            return [UserAuthentication(),]
        if self.request.method == 'GET':
            return [GeneralAuthorization(),]